#include <stdio.h>

#include "funsl.h"
#include "funsl-api.h"

void PrintPacket(const char *msg, int size, unsigned char *packet)
{
    printf("%s packet: id %d, length %d: header %d %d %d %d %d %d %d %d %d %d, data: %d %d %d %d\n", 
            msg, GetPacketID(packet), size, packet[0], packet[1], packet[2], packet[3],
            packet[4], packet[5], packet[6], packet[7], packet[8], packet[9],
            packet[10], packet[11], packet[12], packet[13]);
}

void DecodeRegionHandshake(unsigned char *packet)
{
    unsigned int regionFlags;

    Get_RegionHandshake_RegionInfo(packet, &regionFlags, NULL, NULL, NULL,
            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
            NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
    printf("RegionHandshake: %d\n", regionFlags);
}

void DecodeObjectUpdate(unsigned char *packet)
{
    int i, len;
    unsigned int ID;
    unsigned short timeDilation;

    Get_ObjectUpdate_RegionData(packet, NULL, &timeDilation);
    printf("ObjectUpdate: time dilation %d\n", timeDilation);

    len=Get_ObjectUpdate_ObjectDataBlockSize(packet);
    for(i=0; i<len; i++) {
        Get_ObjectUpdate_ObjectDataBlock(packet, i, &ID, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
                NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
        printf("ObjectUpdate: block %d, ID %d\n", i, ID);
    }



}

int main()
{
    int f, n; /* packet header type and ID */
    int i, size, code;
    char sessionID[40];
    char agentID[40];
    char region_url[200];
    unsigned char *packet=GetPacket();

    /* Login and connect */
    Login("http://localhost:9000", "test", "user", "test", &code, sessionID, agentID, region_url);
    Connect(region_url);

    /* Send some test messages */
    UseCircuitCodeHeader(packet);
    UseCircuitCode_CircuitCode(packet, code, sessionID, agentID);
    SendOutgoingPacket(packet, UseCircuitCodeLength(packet));
    CompleteAgentMovementHeader(packet);
    CompleteAgentMovement_AgentData(packet, agentID, sessionID, code);
    SendOutgoingPacket(packet, CompleteAgentMovementLength(packet));

    /* Get reply packets */
    for(i=0; i<30; i++) {
printf("Waiting for packet %d/30\n", i);
        GetIncomingPacket(packet, &size, 0);
        n=GetPacketID(packet);
        f=GetPacketFrequency(packet);

        if(f==1 && n==12) PrintPacket("SimulatorLoad", size, packet);
        else if(f==1 && n==148) {
            PrintPacket("RegionHandshake", size, packet);
            DecodeRegionHandshake(packet);
            //break;
        } else if(f==1 && n==150) PrintPacket("SimulatorViewerTimeMessage", size, packet);
        else if(f==1 && n==196) PrintPacket("ParcelOverlay", size, packet);
        else if(f==1 && n==250) PrintPacket("AgentMovementComplete", size, packet);
        else if(f==1 && n==65531) PrintPacket("PacketAck", size, packet);
        else if(f==3 && n==12) {
            PrintPacket("ObjectUpdate", size, packet);
            DecodeObjectUpdate(packet);
            //break;
        } else if(f==3 && n==15) PrintPacket("ImprovedTerseObjectUpdate", size, packet);
        else if(f==3 && n==23) PrintPacket("ParcelProperties", size, packet);
        else printf("No packet handler for %d %d\n", GetPacketFrequency(packet), GetPacketID(packet));
    }

    /* Cleanup and exit */
    ReturnPacket(packet);
    Disconnect();

    return 0;
}


